#include <iostream>
#include <cmath>

#include "Spline.h"
#include "iofile.h"


class F1 :public Function{
public:
    double operator()(const double &x)const {
        return 1/(1+25*x*x);
    }
    double diff(const double &x) const{
        return (-50*x)/(1+25*x*x)/(1+25*x*x);
    }
    double diff2(const double &x) const{
        return (-50)/(1+25*x*x)/(1+25*x*x)
                +5000*x*x/(1+25*x*x)/(1+25*x*x)/(1+25*x*x);
    }
};
F1 f1;

void test1(){

    vector<int> knots_num ;
    for(int i=0;i<5;i++){
        knots_num.push_back(5*pow(2,i)+1);
    }

    vector<PPSpline> PPSplines;
    for(auto&it :knots_num){
        PPSpline tmp(-1.0,1.0,f1,it,cubic);
        PPSplines.push_back(tmp);
    }

    vector<double> errors;
    cout << "errors:"<<endl;
    for(int i=0;i<knots_num.size();i++){

        double max_error =0;
        for(int j=0;j<int(knots_num[i]/2.0+2);++j){
            double tmp = -1+(2*j+1)/double(knots_num[i]-1);
            double tmp_error = abs(PPSplines[i](tmp)-f1(tmp));
            if(tmp_error>max_error){
                max_error = tmp_error;
            }
        }
        errors.push_back(max_error);
        cout<< max_error<<" ";
    }

    

    vector<double> xx;
    vector<vector<double>> f_n_x;
    f_n_x.resize(knots_num.size());
    int fitnum = 500;
    for(int i=0;i<=fitnum;i++){
        xx.push_back(-1.0+i/double(fitnum)*2.0);
    }

    for(int i=0;i<knots_num.size();i++){
        for(int j=0;j<=fitnum;j++){
            f_n_x[i].push_back(PPSplines[i](-1.0+j/double(fitnum)*2.0));
        }
    }

    ClearFile("A.txt");
    VectorToFile(xx,"A.txt");
    for(int i=0;i<=knots_num.size()-1;++i){
         VectorToFile(f_n_x[i],"A.txt");
    }
    VectorToFile(errors,"A.txt");


}

int main()
{
   test1();
}
